//
//  BaseViewController.swift
//  Pods
//
//  Created by chenyusen on 2018/3/15.
//

import UIKit
import MBProgressHUD

@objc public protocol KeyboardResizeDelegate {
    @objc optional func keyboardWillAppear(animated: Bool, with bounds: CGRect)
    @objc optional func keyboardWillDisappler(aniamted: Bool, with bounds: CGRect)
    @objc optional func keyboardDidAppear(animated: Bool, with bounds: CGRect)
    @objc optional func keyboardDidDisappear(aniamted: Bool, with bounds: CGRect)
}



open class BaseViewController: UIViewController, KeyboardResizeDelegate {
    
    /// 控制器的View是否已经展示过
    public private(set) var hasViewAppeared: Bool = false
    
    /// 控制器的View是否正在展示
    public private(set) var isViewAppearing: Bool = false
    
    /// 决定是否监控键盘弹出和关闭事件
    public var isAutoresizesForKeyboard: Bool = false {
        didSet {
            if isAutoresizesForKeyboard {
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidHide, object: nil)
                NotificationCenter.default.addObserver(self,
                                                       selector: #selector(keyboardWillShow(_:)),
                                                       name: .UIKeyboardWillShow,
                                                       object: nil)
                
                NotificationCenter.default.addObserver(self,
                                                       selector: #selector(keyboardWillHide(_:)),
                                                       name: .UIKeyboardWillHide,
                                                       object: nil)
                
                NotificationCenter.default.addObserver(self,
                                                       selector: #selector(keyboardDidShow(_:)),
                                                       name: .UIKeyboardDidShow,
                                                       object: nil)
                NotificationCenter.default.addObserver(self,
                                                       selector: #selector(keyboardDidHide(_:)),
                                                       name: .UIKeyboardDidHide,
                                                       object: nil)
            } else {
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
                NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidHide, object: nil)
            }
        }
    }
    
    
    /// 是否自动根据当前控制器所处的层级结构, 自动添加返回按钮
    public var isAutoCreateBackButton: Bool = true
    
    /// 用于控制视图距离顶部的布局
    public var topOffset: CGFloat = 0
    
    private var isScrollViewCreated: Bool = false
    
    /// 是否支持系统手势返回
    private var isGesturePopEnable: Bool = true
    
    /// 加载的Loading
    public var loadingView: UIView?
    
    /// 懒加载一个放置于View上的UIScrollView
    public lazy var scrollView: UIScrollView = {
        let aScrollView = UIScrollView(frame: UIEdgeInsetsInsetRect(view.bounds, UIEdgeInsets(top: topOffset, left: 0, bottom: 0, right: 0)))
        aScrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(aScrollView)
        isScrollViewCreated = true
        if #available(iOS 11.0, *) {
            aScrollView.contentInsetAdjustmentBehavior = .never
        } else {
            self.automaticallyAdjustsScrollViewInsets = false
        }
        return aScrollView
    }()
    
    
    /// 所有继承自BaseViewController的必要构造器
    ///
    /// - Parameter query: 传递的参数
    public required init(query: [AnyHashable: Any]?) {
        super.init(nibName: nil, bundle: nil)
        hidesBottomBarWhenPushed = true
    }
    
    /// WTF
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        isAutoresizesForKeyboard = false
        NotificationCenter.default.removeObserver(self)
        TSLog("\(self) has dealloc")
    }
    
    
    /// 显示/关闭Loading图标
    ///
    /// - Parameter show: 显示/关闭
    open func showLoading(_ show: Bool, text: String? = nil) {
        if show {
            if loadingView == nil {
                var loadingView: UIView!
                if DefaultConfig.View.loading != nil {
                    loadingView = DefaultConfig.View.loading!.init()
                    loadingView.center = CGPoint(x: view.width * 0.5, y: view.height * 0.5)
                    loadingView.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin, .flexibleBottomMargin]
                } else {
                    loadingView = MBProgressHUD(view: view)
                    loadingView.isUserInteractionEnabled = true
                }
                self.loadingView = loadingView
                view.addSubview(loadingView)
                if DefaultConfig.View.loading == nil { // 如果默认没设置为空
                    (loadingView as? MBProgressHUD)?.label.text = text
                    view.bringSubview(toFront: loadingView)
                    (loadingView as? MBProgressHUD)?.show(animated: true)
                }
            }
        } else {
            if DefaultConfig.View.loading == nil {
                loadingView?.removeFromSuperview()
                loadingView = nil
            } else {
                (loadingView as? MBProgressHUD)?.hide(animated: false)
            }
        }
    }
    
    
    // MARK: - View Life Cycle
    
    open override func loadView() {
        super.loadView()
        view.backgroundColor = DefaultConfig.Color.viewControllerBackground
    }
    
    open override func viewDidLoad() {
        super.viewDidLoad()

    }
    
    open override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        hasViewAppeared = true
        isViewAppearing = true
    }
    
    open override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }

    open override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        isViewAppearing = false
    }
    
    open override func didReceiveMemoryWarning() {
        if hasViewAppeared && !isViewAppearing {
            hasViewAppeared = false
            super.didReceiveMemoryWarning()
        } else {
            super.didReceiveMemoryWarning()
        }
    }


    // MARK: - 键盘处理相关
    @objc private func keyboardWillShow(_ notification: Notification) {
        if isViewAppearing {
            resizeForKeyboard(notification, appearing: true)
        }
    }
    @objc private func keyboardWillHide(_ notification: Notification) {
        if isViewAppearing {
            resizeForKeyboard(notification, appearing: false)
        }
    }
    @objc private func keyboardDidShow(_ notification: Notification) {
        if let keyboardBounds = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect {
            (self as KeyboardResizeDelegate).keyboardDidAppear?(animated: false, with: keyboardBounds)
        }
    }
    @objc private func keyboardDidHide(_ notification: Notification) {
        if let keyboardBounds = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect {
            (self as KeyboardResizeDelegate).keyboardDidDisappear?(aniamted: false, with: keyboardBounds)
        }
    }
    
    private func resizeForKeyboard(_ notification: Notification, appearing: Bool) {
        if let keyboardBounds = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect, let curveValue = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? Int, let curve = UIViewAnimationCurve(rawValue: curveValue), let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval {
            UIView.beginAnimations(nil, context: nil)
            UIView.setAnimationCurve(curve)
            UIView.setAnimationDuration(duration)
            if appearing {
                (self as KeyboardResizeDelegate).keyboardWillAppear?(animated: true, with: keyboardBounds)
            } else {
                (self as KeyboardResizeDelegate).keyboardWillDisappler?(aniamted: true, with: keyboardBounds)
            }
            UIView.commitAnimations()
        }
    }
}

